package com.dragon.mmochat.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_1_18C;
import com.dragon.mmochat.message.Mmochat_1_18S;
import com.dragon.mmochat.model.MmochatFileVersion;
import com.skymobi.handler.SkymobiHandler;
import com.skymobi.message.SkymobiProtocolMessage;
import com.skymobi.service.SkymobiService;

//终端资源文件版本更新控制
public class MmochatClientVerionServer {
	private static Logger log = LoggerFactory
			.getLogger(MmochatClientVerionServer.class);

	public static ScheduledExecutorService checkFileThread = Executors
			.newScheduledThreadPool(1);

	private static List<MmochatFileVersion> clientFiles = new ArrayList<MmochatFileVersion>();// 非KA文件资源
	private static List<MmochatFileVersion> ka_clientFiles = new ArrayList<MmochatFileVersion>();// KA文件资源
	private static List<MmochatFileVersion> spr_clientFiles = new ArrayList<MmochatFileVersion>();// SPR文件资源

	private static long lastModifyTimeOfClientResVersionFile = 0;

	// 记录服务器运行以来需要下载更新的玩家数(可能有重复计算)，与注册用户数比对，可以初略观察下载流失率
	public static int needUpdatePlayerNum = 0;

	public void init() {
		if (!MmochatMain.openMergeServer) {
			// 每分钟判断一次是否需要从配置文件重新读取clientVersion
			checkFileThread.scheduleWithFixedDelay(new loadClientResVersion(),
					0, 1, TimeUnit.MINUTES);
		}
	}

	class loadClientResVersion implements Runnable {
		public void run() {
			try {
				File file = new File("config/clientResourceConfig.xml");
				if (file.isFile()) {
					if (lastModifyTimeOfClientResVersionFile == file
							.lastModified()) {
						// 未修改
						return;
					}
					log.debug("start loading resVersion...");
					lastModifyTimeOfClientResVersionFile = file.lastModified();

					DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder docBuilder;
					docBuilder = docBuilderFactory.newDocumentBuilder();
					Document doc = docBuilder.parse(file);
					doc.getDocumentElement().normalize();

					clientFiles.clear();
					ka_clientFiles.clear();
					spr_clientFiles.clear();
					NodeList nodeList = doc.getElementsByTagName("资源文件");
					for (int s = 0; s < nodeList.getLength(); s++) {
						Node resNode = nodeList.item(s);
						if (resNode.getNodeType() == Node.ELEMENT_NODE) {
							Element resElement = (Element) resNode;
							MmochatFileVersion fileInfo = new MmochatFileVersion();
							// 文件名
							{
								NodeList subElement = resElement
										.getElementsByTagName("文件名");
								String str = subElement.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								fileInfo.setFileName(str);
							}
							// 版本号
							{
								NodeList subElement = resElement
										.getElementsByTagName("版本号");
								String str = subElement.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								int num = Integer.parseInt(str);
								fileInfo.setVersion(num);
							}
							// 分包数
							{
								NodeList subElement = resElement
										.getElementsByTagName("分包数");
								String str = subElement.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								int num = Integer.parseInt(str);
								fileInfo.setSubPackNum(num);
							}
							// 是否为KA；默认为非KA
							NodeList subElement = resElement
									.getElementsByTagName("类别");
							if (subElement != null
									&& subElement.getLength() > 0) {
								String str = subElement.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								if (str != null && str.equals("体验")) {
									ka_clientFiles.add(fileInfo);
								} else if (str != null && str.equals("SPR")) {
									spr_clientFiles.add(fileInfo);
								} else {
									clientFiles.add(fileInfo);
								}
							} else {
								clientFiles.add(fileInfo);
							}
						}
					}
				}
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 上传终端版本信息
	@SkymobiService
	public SkymobiProtocolMessage handleC_1_18(SkymobiHandler handler,
			Mmochat_1_18C req) {
		List<MmochatFileVersion> needUpdateFiles = new ArrayList<MmochatFileVersion>();
		List<Integer> versions = req.getVersions();

		List<MmochatFileVersion> resFiles = null;
		if (versions.size() > 0) {
			Integer ver = versions.get(0);
			if (ver != null && ver < 0) {
				// SPR版本会提交一个负数的版本号，以区分SPR和MTK
				resFiles = spr_clientFiles;
				versions.set(0, -1 * ver);
			}
		}
		if (resFiles == null) {
			// 列表服务器是不区分KA与非KA的，通过不同的终端模块号，下发KA和非KA专区
			if (req.getSrcId() == MmochatConstant.ka_clientModuleId) {
				resFiles = ka_clientFiles;
			} else {
				resFiles = clientFiles;
			}
		}

		int index = 0;
		for (Integer ver : versions) {
			if (index >= resFiles.size()) {
				log.error("1.18协议出错!versions.size=" + versions.size()
						+ ",clientFiles.size=" + resFiles.size());
				break;
			}
			MmochatFileVersion fileVersion = resFiles.get(index);
			if (fileVersion != null) {
				if (fileVersion.getVersion() != ver) {
					needUpdateFiles.add(fileVersion);
				}
			}
			index++;
		}
		if (needUpdateFiles.size() > 0) {
			needUpdatePlayerNum++;
		}
		Mmochat_1_18S pack = new Mmochat_1_18S();
		pack.setNeedUpdateFiles(needUpdateFiles);
		return pack;
	}
}
